package cate.game.role.res.holy_pet;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDObj;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDRank;
import cate.common.table.res.holy_pet.base.HolyPetBaseRow;
import cate.common.table.res.holy_pet.closeness.HolyPetClosenessRow;
import cate.common.table.res.holy_pet.favor_item.HolyPetFavorItemRow;
import cate.common.table.res.holy_pet.favor_level.HolyPetFavorLevelRow;
import cate.common.table.res.holy_pet.favor_sum.HolyPetFavorSumRow;
import cate.common.table.res.holy_pet.fight.HolyPetFightRow;
import cate.common.table.res.holy_pet.practice.HolyPetPracticeRow;
import cate.common.table.res.holy_pet.scene_spot.HolyPetSceneSpotRow;
import cate.common.util.GameResult;
import cate.common.util.TimeTool;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResConsumer;
import cate.game.res.MixResItem;
import cate.game.res.holy_pet.HolyPetConstants;
import cate.game.res.holy_pet.core.HolyPetRoleMission;
import cate.game.res.holy_pet.core.HolyPetSingleMission;
import cate.game.role.FuncOpenChecker;
import cate.game.role.Role;
import cate.game.role.friend.Friend;
import cate.game.role.res.holy_pet.core.*;
import cate.game.role.res.holy_pet.msg.HolyPetFightPositionResp;
import cate.game.role.res.holy_pet.msg.HolyPetMainInfoResp;
import cate.game.role.res.holy_pet.msg.HolyPetSupportListResp;
import cate.game.role.task.TaskGroup;
import com.fasterxml.jackson.annotation.JsonIgnore;
import cp.solution.util.collection.ListKit;
import easy.java.dev.note.NoteField;

import java.util.*;

/**
 * 灵宠
 *
 * @author ShenSL
 * @since 2023/8/23 11:04
 */
public class RoleHolyPet extends FuncOpenChecker {
    @NoteField("灵宠Map")
    public Map<Integer, SingleHolyPetPO> pets;
    @NoteField("场景Map")
    public Map<Integer, SingleScenePO> scenes;
    @NoteField("冒险日志")
    public List<HolyPetAdventureLog> adventureLogs;
    @NoteField("已消耗的精力")
    public int energyUsed;
    @NoteField("已协助次数")
    public int supportUsed;
    @NoteField("协助排行次数")
    public int supportCount;
    @NoteField("战斗方案")
    public Map<Integer, HolyPetPosition> positions;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (pets == null) {
            pets = new HashMap<>();
        }
        if (scenes == null) {
            scenes = new HashMap<>();
        }
        if (adventureLogs == null) {
            adventureLogs = new ArrayList<>();
        }
        if (positions == null) {
            positions = new HashMap<>();
        }
        checkPets();
        checkPetAutoActive();
        checkTasks();
        // 以防配置修改 检测升级
        pets.values().forEach(petPO -> {
            checkFavorLevelUp(petPO);
            checkClosenessLevelUp(petPO);
        });
        checkScenes();
        checkSceneActive();
        for (int i = 1; i <= HolyPetConstants.FIGHT_POS_NUM; i++) {
            if (!positions.containsKey(i)) {
                positions.put(i, new HolyPetPosition());
            }
        }
        positions.values().forEach(pos -> pos.initialize(game().table.holyPet.fight.getMax()));
    }

    @Override
    public void onEnter() {
        super.onEnter();
        addAdventureLogs(game().res.holyPet.getAndDropCachedLogs(role.getUid()));
    }

    @Override
    public int getFuncId() {
        return GDFunc.HOLY_PET;
    }

    @Override
    public void onAfterOpen() {
        // 开启时检测一下任务
        checkTasks();
        // 检测一下自动激活
        checkPetAutoActive();
        // 检测一下场景
        checkScenes();
        // 发消息
        initSend();
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        energyUsed = 0;
        supportUsed = 0;
        if (!silence) {
            noticeUpdate();
        }
    }

    @Override
    public void onWeekSpan(boolean silence) {
        super.onWeekSpan(silence);
        supportCount = 0;
    }

    /**
     * 检测灵宠配置
     */
    private void checkPets() {
        pets.entrySet().removeIf(e -> game().table.holyPet.base.get(e.getKey()) == null);
        game().table.holyPet.base.getList().forEach(baseRow -> {
            if (!pets.containsKey(baseRow.id)) {
                SingleHolyPetPO petPO = new SingleHolyPetPO(baseRow.id);
                pets.put(petPO.getPetId(), petPO);
            }
        });
    }

    /**
     * 检测任务添加
     */
    private void checkTasks() {
        if (!isOpen()) {
            return;
        }
        TaskGroup taskGroup = role.getTask().getGroup(getFuncId());
        List<Integer> allTasks = game().table.holyPet.base.getList().stream()
                .map(row -> row.taskIds)
                .collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);
        taskGroup.addItemListNoRepeat(allTasks);
    }

    /**
     * 检测灵宠激活
     */
    private void checkPetAutoActive() {
        if (!isOpen()) {
            return;
        }
        TaskGroup taskGroup = role.getTask().getGroup(getFuncId());
        pets.values().forEach(petPO -> {
            if (petPO.isActive()) {
                return;
            }
            HolyPetBaseRow baseRow = game().table.holyPet.base.get(petPO.getPetId());
            if (baseRow == null) {
                return;
            }
            if (baseRow.taskIds.isEmpty()) {
                petPO.setActive(true);
            }
        });
    }

    /**
     * 检测场景配置
     */
    private void checkScenes() {
        scenes.entrySet().removeIf(e -> game().table.holyPet.scene_spot.getList().stream()
                .noneMatch(row -> row.sceneId == e.getKey()));
        game().table.holyPet.scene_spot.getScenes().forEach(sceneId -> {
            if (!scenes.containsKey(sceneId)) {
                SingleScenePO scenePO = new SingleScenePO();
                scenePO.setSceneId(sceneId);
                scenePO.setPlaceId(game().table.holyPet.scene_spot.getRandomPlace(sceneId, -1));
                scenes.put(scenePO.getSceneId(), scenePO);
            }
        });
    }

    /**
     * 检测场景激活
     */
    private void checkSceneActive() {
        int sum = getFavorLevelSum();
        scenes.values().forEach(scenePO -> {
            if (scenePO.isActive()) {
                return;
            }
            if (sum >= game().table.holyPet.scene_spot.favorSumForScene(scenePO.getSceneId())) {
                scenePO.setActive(true);
            }
        });
    }

    /**
     * 同布消息到前端
     */
    public void noticeUpdate() {
        if (!isOpen()) {
            return;
        }
        Map<Integer, SingleSceneVO> vos = new HashMap<>();
        scenes.forEach((k, v) -> {
            HolyPetSingleMission mission = Optional.ofNullable(game().res.holyPet.data.roleMissionMap.get(role.getUid()))
                    .map(rm -> rm.missions.get(k))
                    .orElse(null);
            SingleSceneVO vo = new SingleSceneVO(v, mission);
            vos.put(k, vo);
        });
        role.sendNow(new HolyPetMainInfoResp(pets, vos, energyUsed, supportUsed));
    }

    /**
     * 同布协助列表到前端
     */
    public void noticeSupport() {
        if (!isOpen()) {
            return;
        }
        role.sendNow(new HolyPetSupportListResp(game().res.holyPet.getSupportList(role)));
    }

    /**
     * 同布战斗方案到前端
     */
    public void noticePositions() {
        if (!isOpen()) {
            return;
        }
        role.sendNow(new HolyPetFightPositionResp(positions));
    }

    /**
     * 登录发送
     */
    public void initSend() {
        noticeUpdate();
        noticeSupport();
        noticePositions();
    }

    /**
     * 激活灵宠
     *
     * @param id 灵宠ID
     * @return 激活结果
     */
    public GameResult<Void> activePet(int id) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!pets.containsKey(id)) {
            return r.fail("灵宠不存在");
        }
        SingleHolyPetPO petPO = pets.get(id);
        if (petPO.isActive()) {
            return r.fail("不能重复激活");
        }
        HolyPetBaseRow baseRow = game().table.holyPet.base.get(id);
        if (baseRow == null) {
            return r.fail("配置错误");
        }
        TaskGroup taskGroup = role.getTask().getGroup(getFuncId());
        if (baseRow.taskIds.stream().anyMatch(taskId -> taskGroup.getItem(taskId) == null || !taskGroup.getItem(taskId).rewardGot)) {
            return r.fail("结交任务未完成");
        }
        MixRes cost = new MixRes().addItem(new MixResItem(GDObj.Type.PROP, baseRow.favorItem, 1));
        if (!cost.isEmpty()) {
            GameResult<MixResItem> r_cost = cost.consumeCheck(role);
            if (!r_cost.ok()) {
                return r.fail(r_cost);
            }
        }
        new MixResConsumer<Void>().res(cost)
                .tips(true)
                .operation(GDOperation.HOLY_PET_ACTIVE, id)
                .exe(role);
        return r.success();
    }

    /**
     * 好感升级
     *
     * @param id      灵宠ID
     * @param consume 具体消耗
     * @return 升级结果
     */
    public GameResult<Void> favorLevelUp(int id, MixRes consume) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (consume.items.stream().anyMatch(item -> item.num <= 0)) {
            return r.fail("非法消耗");
        }
        if (!pets.containsKey(id)) {
            return r.fail("灵宠不存在");
        }
        SingleHolyPetPO petPO = pets.get(id);
        if (!petPO.isActive()) {
            return r.fail("灵宠未激活");
        }
        HolyPetBaseRow baseRow = game().table.holyPet.base.get(id);
        if (baseRow == null) {
            return r.fail("配置错误");
        }
        HolyPetFavorLevelRow nextLevelRow = game().table.holyPet.favor_level.get(petPO.getFavorLevel() + 1);
        if (nextLevelRow == null) {
            return r.fail("灵宠好感度已满级");
        }
        GameResult<MixResItem> r_cost = consume.consumeCheck(role);
        if (!r_cost.ok()) {
            return r.fail(r_cost);
        }
        long exp = 0L;
        for (MixResItem item : consume.getCombinedItems()) {
            HolyPetFavorItemRow itemRow = game().table.holyPet.favor_item.get(item.tid);
            if (itemRow == null) {
                return r.fail("不能消耗非好感道具");
            }
            if (item.tid == baseRow.favorItem) {
                exp += itemRow.exp * item.num * 2;
            } else {
                exp += itemRow.exp * item.num;
            }
        }
        new MixResConsumer<Void>().res(consume)
                .tips(true)
                .operation(GDOperation.HOLY_PET_FAVOR_LEVEL, id)
                .exe(role);
        petPO.changeFavorExp(exp);
        checkFavorLevelUp(petPO);
        return r.success();
    }

    /**
     * 检测好感升级
     *
     * @param petPO 灵宠
     */
    private void checkFavorLevelUp(SingleHolyPetPO petPO) {
        if (petPO.getFavorLevel() >= game().table.holyPet.favor_level.maxLevel) {
            return;
        }
        for (int i = petPO.getFavorLevel(); i < game().table.holyPet.favor_level.maxLevel; i++) {
            HolyPetFavorLevelRow levelRow = game().table.holyPet.favor_level.get(petPO.getFavorLevel());
            if (levelRow == null) {
                break;
            }
            if (petPO.getFavorExp() < levelRow.needExp) {
                break;
            }
            petPO.changeFavorExp(-levelRow.needExp);
            petPO.setFavorLevel(petPO.getFavorLevel() + 1);
        }
        if (petPO.getFavorLevel() == game().table.holyPet.favor_level.maxLevel) {
            petPO.setFavorExp(0L);
        }
        // 检测一下场景解锁
        checkSceneActive();
    }

    /**
     * 亲密升级
     *
     * @param id 灵宠ID
     * @return 升级结果
     */
    public GameResult<Void> closenessLevelUp(int id) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!pets.containsKey(id)) {
            return r.fail("灵宠不存在");
        }
        SingleHolyPetPO petPO = pets.get(id);
        if (!petPO.isActive()) {
            return r.fail("灵宠未激活");
        }
        if (petPO.getClosenessLevel() >= game().table.holyPet.closeness.getMaxLevel(petPO.getPetId())) {
            return r.fail("亲密等级已达上限");
        }
        HolyPetClosenessRow row = game().table.holyPet.closeness.getRow(petPO.getPetId(), petPO.getClosenessLevel());
        if (row == null) {
            return r.fail("配置错误");
        }
        if (petPO.getFavorLevel() < row.needFavorLevel) {
            return r.fail("灵宠好感等级不足");
        }
        MixRes cost = new MixRes(row.singleCost);
        GameResult<MixResItem> r_cost = cost.consumeCheck(role);
        if (!r_cost.ok()) {
            return r.fail(r_cost);
        }
        new MixResConsumer<Void>().res(cost)
                .tips(true)
                .operation(GDOperation.HOLY_PET_CLOSENESS_LEVEL, id)
                .exe(role);
        petPO.changeClosenessExp(row.singleExp);
        checkClosenessLevelUp(petPO);
        return r.success();
    }

    /**
     * 检测亲密升级
     *
     * @param petPO 灵宠
     */
    private void checkClosenessLevelUp(SingleHolyPetPO petPO) {
        if (petPO.getClosenessLevel() >= game().table.holyPet.closeness.getMaxLevel(petPO.getPetId())) {
            return;
        }
        for (int i = petPO.getClosenessLevel(); i < game().table.holyPet.closeness.getMaxLevel(petPO.getPetId()); i++) {
            HolyPetClosenessRow levelRow = game().table.holyPet.closeness.getRow(petPO.getPetId(), petPO.getClosenessLevel());
            if (levelRow == null) {
                break;
            }
            if (petPO.getClosenessExp() < levelRow.needExp) {
                break;
            }
            petPO.changeClosenessExp(-levelRow.needExp);
            petPO.setClosenessLevel(petPO.getClosenessLevel() + 1);
        }
        if (petPO.getClosenessLevel() == game().table.holyPet.closeness.getMaxLevel(petPO.getPetId())) {
            petPO.setClosenessExp(0L);
        }
    }

    /**
     * 修炼升级
     *
     * @param id 灵宠ID
     * @return 升级结果
     */
    public GameResult<Void> practiceLevelUp(int id) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!pets.containsKey(id)) {
            return r.fail("灵宠不存在");
        }
        SingleHolyPetPO petPO = pets.get(id);
        if (!petPO.isActive()) {
            return r.fail("灵宠未激活");
        }
        if (petPO.getPracticeLevel() >= game().table.holyPet.practice.maxLevel) {
            return r.fail("灵宠修炼等级已达上限");
        }
        HolyPetPracticeRow row = game().table.holyPet.practice.get(petPO.getPracticeLevel());
        if (row == null) {
            return r.fail("配置错误");
        }
        if (petPO.getFavorLevel() < row.needFavorLevel) {
            return r.fail("灵宠好感等级不足");
        }
        MixRes cost = new MixRes(row.costStr);
        GameResult<MixResItem> r_cost = cost.consumeCheck(role);
        if (!r_cost.ok()) {
            return r.fail(r_cost);
        }
        new MixResConsumer<Void>().res(cost)
                .tips(true)
                .operation(GDOperation.HOLY_PET_PRACTICE_LEVEL, id)
                .exe(role);
        petPO.setPracticeLevel(petPO.getPracticeLevel() + 1);
        return r.success();
    }

    /**
     * 获取总好感等级
     */
    @JsonIgnore
    public int getFavorLevelSum() {
        return pets.values().stream().filter(SingleHolyPetPO::isActive)
                .mapToInt(SingleHolyPetPO::getFavorLevel)
                .sum();
    }

    /**
     * 刷新场景
     *
     * @param sceneId 场景ID
     * @return 刷新结果
     */
    public GameResult<Void> refreshScenePlace(int sceneId) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!scenes.containsKey(sceneId)) {
            return r.fail("场景不存在");
        }
        SingleScenePO scenePO = scenes.get(sceneId);
        if (!scenePO.isActive()) {
            return r.fail("场景未解锁");
        }
        if (scenePO.getReward() != null) {
            return r.fail("请先领取任务奖励");
        }
        HolyPetRoleMission roleMission = game().res.holyPet.data.roleMissionMap.get(role.getUid());
        if (roleMission != null && roleMission.missions.containsKey(sceneId)) {
            return r.fail("派遣中无法刷新");
        }
        MixRes cost = new MixRes(HolyPetConstants.REFRESH_COST);
        GameResult<MixResItem> r_cost = cost.consumeCheck(role);
        if (!r_cost.ok()) {
            return r.fail(r_cost);
        }
        new MixResConsumer<Void>().res(cost)
                .tips(true)
                .operation(GDOperation.HOLY_PET_SCENE_REFRESH, 0)
                .exe(role);
        scenePO.setPlaceId(game().table.holyPet.scene_spot.getRandomPlace(scenePO.getSceneId(), scenePO.getPlaceId()));
        return r.success();
    }

    /**
     * 领取派遣奖励
     *
     * @param sceneId 场景ID
     * @return 领取结果
     */
    public GameResult<Void> receiveSceneReward(int sceneId) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!scenes.containsKey(sceneId)) {
            return r.fail("场景不存在");
        }
        SingleScenePO scenePO = scenes.get(sceneId);
        if (!scenePO.isActive()) {
            return r.fail("场景未解锁");
        }
        if (scenePO.getReward() == null) {
            return r.fail("没有可领取奖励");
        }
        MixRes reward = scenePO.getReward();
        scenePO.setReward(null);
        new MixResAdder().setRes(reward)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .setOperation(GDOperation.HOLY_PET_SCENE_REWARD)
                .exe(role);
        return r.success();
    }

    /**
     * 发起派遣
     *
     * @param sceneId 场景ID
     * @param petId   灵宠ID
     * @return 发起结果
     */
    public GameResult<Void> startSceneMission(int sceneId, int petId) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (!scenes.containsKey(sceneId)) {
            return r.fail("场景不存在");
        }
        SingleScenePO scenePO = scenes.get(sceneId);
        if (!scenePO.isActive()) {
            return r.fail("场景未解锁");
        }
        if (!pets.containsKey(petId)) {
            return r.fail("灵宠不存在");
        }
        SingleHolyPetPO petPO = pets.get(petId);
        if (!petPO.isActive()) {
            return r.fail("灵宠未激活");
        }
        HolyPetBaseRow baseRow = game().table.holyPet.base.get(petId);
        if (baseRow == null) {
            return r.fail("灵宠配置错误");
        }
        if (scenePO.getReward() != null) {
            return r.fail("请先领取任务奖励");
        }
        HolyPetRoleMission roleMission = game().res.holyPet.data.roleMissionMap.get(role.getUid());
        if (roleMission != null && roleMission.missions.containsKey(sceneId)) {
            return r.fail("场景正在派遣中");
        }
        if (roleMission != null && roleMission.missions.values().stream().anyMatch(mission -> mission.getPetId() == petId)) {
            return r.fail("灵宠无法重复派遣");
        }
        HolyPetSceneSpotRow spotRow = game().table.holyPet.scene_spot.getRow(sceneId, scenePO.getPlaceId());
        if (spotRow == null) {
            return r.fail("配置错误");
        }
        HolyPetFavorSumRow sumRow = game().table.holyPet.favor_sum.get(getFavorLevelSum());
        if (sumRow == null) {
            return r.fail("精力配置错误");
        }
        if (energyUsed + spotRow.needEnergy > sumRow.energy) {
            return r.fail("精力不足");
        }
        energyUsed += spotRow.needEnergy;
        long nowTime = System.currentTimeMillis();
        HolyPetSingleMission mission = new HolyPetSingleMission();
        mission.setSceneId(sceneId);
        mission.setPlaceId(scenePO.getPlaceId());
        mission.setPetId(petId);
        mission.setStartTime(nowTime);
        mission.setEndTime(nowTime + spotRow.missionTimeSec * TimeTool.TimeCons.SECOND);
        MixRes reward = new MixRes(spotRow.missionRewardStr);
        if (baseRow.favorPlace == scenePO.getPlaceId()) {
            reward.multiply(2L);
        }
        mission.setReward(reward);
        game().res.holyPet.addRoleMission(role, mission);
        return r.success();
    }

    /**
     * 协助
     *
     * @param targetUid   对方UID
     * @param sceneId     场景ID
     * @param adventureId 事件ID
     * @return 协助结果
     */
    public GameResult<Void> supportMission(String targetUid, int sceneId, int adventureId) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        Friend friend = role.getFriend().getFriend(targetUid);
        if (friend == null) {
            return r.fail("非好友无法协助");
        }
        if (supportUsed >= HolyPetConstants.DAILY_SUPPORT_MAX) {
            return r.fail("今日协助次数已用完");
        }
        GameResult<MixRes> r_support = game().res.holyPet.support(role, targetUid, sceneId, adventureId);
        if (!r_support.ok()) {
            return r.fail(r_support);
        }
        supportUsed++;
        new MixResAdder().setRes(r_support.data)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .setOperation(GDOperation.HOLY_PET_SUPPORT_REWARD)
                .exe(role);
        // 跨服添加排行次数
        supportCount++;
        game().crossRank.recordValue(role, GDRank.Id.HOLY_PET_SUPPORT, supportCount);
        return r.success();
    }

    /**
     * 设置方案
     *
     * @param index    位置
     * @param position 布阵方案
     * @return 设置结果
     */
    public GameResult<Void> setupFightPosition(int index, HolyPetPosition position) {
        GameResult<Void> r = new GameResult<>();
        if (!positions.containsKey(index)) {
            return r.fail("方案序号不存在");
        }
        if (position == null) {
            return r.fail("非法参数");
        }
        if (position.getPetPos() != null) {
            Set<Integer> petSet = new HashSet<>();
            for (int petId : position.getPetPos().values()) {
                if (petId != 0 && petSet.contains(petId)) {
                    return r.fail("战宠不能重复上阵");
                }
                petSet.add(petId);
            }
        }
        int sum = getFavorLevelSum();
        if (position.getPetPos() != null) {
            for (int pos : position.getPetPos().keySet()) {
                HolyPetFightRow fightRow = game().table.holyPet.fight.get(pos);
                if (fightRow == null) {
                    return r.fail("非法位置");
                }
                int petId = position.getPetPos().get(pos);
                if (petId == 0) {
                    continue;
                }
                if (!pets.containsKey(petId) || !pets.get(petId).isActive()) {
                    return r.fail("灵宠未激活");
                }
                if (sum < fightRow.needFavorSum) {
                    return r.fail("灵宠总等级不足无法上阵");
                }
            }
        }
        positions.get(index).readFromPosition(position);
        return r.success();
    }

    /**
     * 根据序号获取战斗方案
     *
     * @param index 序号
     */
    public HolyPetFightPosition getFightPosition(int index) {
        HolyPetPosition position = positions.get(index);
        Map<Integer, HolyPetFightParam> params = new HashMap<>();
        game().table.holyPet.fight.getList().forEach(fightRow -> {
            if (position != null && position.getPetPos().containsKey(fightRow.id)) {
                int petId = position.getPetPos().get(fightRow.id);
                SingleHolyPetPO petPO = pets.get(petId);
                if (petPO == null) {
                    //params.put(fightRow.id, HolyPetFightParam.EMPTY(fightRow.round));
                    return;
                }
                HolyPetClosenessRow closenessRow = game().table.holyPet.closeness.getRow(petId, petPO.getClosenessLevel());
                if (closenessRow == null) {
                    //params.put(fightRow.id, HolyPetFightParam.EMPTY(fightRow.round));
                    return;
                }
                HolyPetPracticeRow practiceRow = game().table.holyPet.practice.get(petPO.getPracticeLevel());
                params.put(fightRow.id, new HolyPetFightParam(fightRow.round, petId, closenessRow.skillId,
                        Optional.ofNullable(practiceRow).map(row -> row.extraDamage).orElse(0L)));
            }
        });
        return new HolyPetFightPosition(params);
    }

    /**
     * 添加单条机缘日志
     */
    public void addAdventureLog(HolyPetAdventureLog log) {
        if (adventureLogs.size() >= HolyPetConstants.MAX_ADVENTURE_LOG_NUM) {
            adventureLogs = ListKit.trimMaxKeepTail(adventureLogs, HolyPetConstants.MAX_ADVENTURE_LOG_NUM - 1);
        }
        adventureLogs.add(log);
    }

    /**
     * 添加多条机缘日志
     */
    public void addAdventureLogs(List<HolyPetAdventureLog> logs) {
        if (ListKit.isEmpty(logs)) {
            return;
        }
        if (logs.size() >= HolyPetConstants.MAX_ADVENTURE_LOG_NUM) {
            adventureLogs = ListKit.trimMaxKeepTail(logs, HolyPetConstants.MAX_ADVENTURE_LOG_NUM);
        } else {
            adventureLogs = ListKit.trimMaxKeepTail(adventureLogs, HolyPetConstants.MAX_ADVENTURE_LOG_NUM - logs.size());
            adventureLogs.addAll(logs);
        }
    }
}
